import axios from "axios";
import { AxiosRequestConfig, AxiosResponse } from "axios";
import { ElMessage } from 'element-plus'
import router from '../router'

// 创建新的实例 修改他
const http = axios.create({
    // 向新的实例中传参 来修改这个实例
    baseURL: import.meta.env.VITE_BASE_URL,
    timeout: 600000,
    headers:{'Content-Type':'application/json;charset=utf-8'}
});

// 添加请求拦截器 在发请求之前处理一下
http.interceptors.request.use((config: any) => {
    return config;
}, (error: any) => {
    ElMessage.error(error.message)
    return Promise.reject(error);
})

// 添加响应拦截器 在得到数据之后处理一下
http.interceptors.response.use((data: any) => {
    if(data.data instanceof Blob){
        return data;
    }
    const result = data.data as Result
    if(result.code === '500'){
        ElMessage.error(result.msg)
    }
    if(result.code === '600' ){
        ElMessage.error(result.msg)
        router.push({
            path: '/login'
        })
    }
    return data;
}, (error: any) => {
    ElMessage.error(error.message)
    return Promise.reject(error);
})

type Result<T = any> = {
    msg: string
    code: String
    data: T
}
  
  // AxiosRequestConfig从axios中导出的，将config声明为AxiosRequestConfig，这样我们调用函数时就可以获得TS带来的类型提示
  // 泛型T用来指定Reponse类型中result的类型
export default <T> (config: AxiosRequestConfig) => {
    // 指定promise实例成功之后的回调函数的第一个参数的类型为Response<T>
    return new Promise<Result<T>>((resolve, reject) => {
      // instance是我们在上面创建的axios的实例
      // 我们指定instance.request函数的第一个泛型为Response，并把Response的泛型指定为函数的泛型T
      // 第二个泛型AxiosResponse的data类型就被自动指定为Response<T>
      // AxiosResponse从axios中导出的，也可以不指定，TS会自动类型推断
      http.request<Result<T>>(config).then((response: AxiosResponse<Result<T>>) => {
        // response类型就是AxiosResponse<Response<T>>，而data类型就是我们指定的Response<T>
        // 请求成功后就我们的数据从response取出并使返回的promise实例的状态变为成功的
        resolve(response.data)
      }).catch((error :any) => {
        // 请求失败的处理
        reject(error)
      })
    })
}